// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Linq.Expressions;

namespace SnapObjects.Expressions
{
    internal class WrapShellOperator
    {
        public static Expression<Func<object, Type, object, Type, object>> Add
            => (left, leftType, right, rightType)
                => ObjectOperator.Add(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Subtract
            => (left, leftType, right, rightType)
                => ObjectOperator.Subtract(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Multiply
            => (left, leftType, right, rightType)
                => ObjectOperator.Multiply(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Division
            => (left, leftType, right, rightType)
                => ObjectOperator.Division(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Modulus
            => (left, leftType, right, rightType)
                => ObjectOperator.Modulus(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Caret
            => (left, leftType, right, rightType)
                => ObjectOperator.Caret(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> OrElse
            => (left, leftType, right, rightType)
                => ObjectOperator.OrElse(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> AndAlso
            => (left, leftType, right, rightType)
                => ObjectOperator.AndAlso(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> And
            => (left, leftType, right, rightType)
                => ObjectOperator.And(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Or
            => (left, leftType, right, rightType)
                => ObjectOperator.Or(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> Equal
            => (left, leftType, right, rightType)
                => ObjectOperator.Equal(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> NotEqual
            => (left, leftType, right, rightType)
                => ObjectOperator.NotEqual(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> LessThan
            => (left, leftType, right, rightType)
                => ObjectOperator.LessThan(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> GreaterThan
            => (left, leftType, right, rightType)
                => ObjectOperator.GreaterThan(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> LessThanOrEqual
            => (left, leftType, right, rightType)
                => ObjectOperator.LessThanOrEqual(left, leftType, right, rightType).Value;
        public static Expression<Func<object, Type, object, Type, object>> GreaterThanOrEqual
            => (left, leftType, right, rightType)
                => ObjectOperator.GreaterThanOrEqual(left, leftType, right, rightType).Value;

        public static bool Check(Expression left, Expression right)
        {
            return (left.Type == typeof(object) && right.Type == typeof(object))
                || (left.Type == typeof(object) && right.Type == typeof(string))
                || (right.Type == typeof(object) && left.Type == typeof(string))
                || (left.Type == typeof(object) && right.Type.IsValueType)
                || (right.Type == typeof(object) && left.Type.IsValueType);
        }
    }
}
